
package ru.samgtu.wst.ui.swing;

import ru.samgtu.wst.model.Cookie;
import ru.samgtu.wst.model.FrameworkEvent;
import ru.samgtu.wst.model.FrameworkListener;
import ru.samgtu.wst.model.FrameworkModel;
import ru.samgtu.wst.util.swing.TableSorter;

import javax.swing.table.AbstractTableModel;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;

import java.awt.Color;

import java.util.Date;
import java.util.logging.Logger;


public class CookieJarViewer extends javax.swing.JFrame {

	private FrameworkModel _model;
	private CookieTableModel _cookieTableModel;
	private HistoricalCookieTableModel _detailTableModel;

	private Logger _logger = Logger.getLogger(getClass().getName());

	private String _key = null;

	/** Creates new form CookieJarViewer */
	public CookieJarViewer(FrameworkModel model) {
		_model = model;
		initComponents();
		_cookieTableModel = new CookieTableModel(_model);
		cookieTable.setModel(new TableSorter(_cookieTableModel, cookieTable
				.getTableHeader()));
		_detailTableModel = new HistoricalCookieTableModel(_model);
		cookieDetailTable.setModel(new TableSorter(_detailTableModel,
				cookieDetailTable.getTableHeader()));
		cookieTable.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent evt) {
						if (evt.getValueIsAdjusting()) {
							return;
						}
						int row = cookieTable.getSelectedRow();
						if (row > -1) {
							_key = _cookieTableModel.getKeyAt(row);
						} else {
							_key = null;
						}
						_detailTableModel.setKey(_key);
					}
				});
		addDialog.pack();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// desc=" Generated Code ">//GEN-BEGIN:initComponents
	private void initComponents() {
		java.awt.GridBagConstraints gridBagConstraints;

		addDialog = new javax.swing.JDialog();
		jLabel6 = new javax.swing.JLabel();
		domainTextField = new javax.swing.JTextField();
		jLabel4 = new javax.swing.JLabel();
		pathTextField = new javax.swing.JTextField();
		jLabel5 = new javax.swing.JLabel();
		nameTextField = new javax.swing.JTextField();
		jLabel3 = new javax.swing.JLabel();
		valueTextField = new javax.swing.JTextField();
		jPanel2 = new javax.swing.JPanel();
		okButton = new javax.swing.JButton();
		cancelButton = new javax.swing.JButton();
		jLabel1 = new javax.swing.JLabel();
		jScrollPane1 = new javax.swing.JScrollPane();
		cookieTable = new javax.swing.JTable();
		jLabel2 = new javax.swing.JLabel();
		jScrollPane2 = new javax.swing.JScrollPane();
		cookieDetailTable = new javax.swing.JTable();
		closeButton = new javax.swing.JButton();
		jPanel1 = new javax.swing.JPanel();
		addButton = new javax.swing.JButton();
		deleteButton = new javax.swing.JButton();

		addDialog.getContentPane().setLayout(new java.awt.GridBagLayout());

		addDialog.setTitle("Add Cookie");
		addDialog.setLocationRelativeTo(null);
		addDialog.setModal(true);
		addDialog.setName("Add Cookie");
		addDialog.setResizable(false);
		jLabel6.setText("Domain : ");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
		addDialog.getContentPane().add(jLabel6, gridBagConstraints);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		addDialog.getContentPane().add(domainTextField, gridBagConstraints);

		jLabel4.setText("Path : ");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
		addDialog.getContentPane().add(jLabel4, gridBagConstraints);

		pathTextField.setMinimumSize(new java.awt.Dimension(200, 19));
		pathTextField.setPreferredSize(new java.awt.Dimension(400, 19));
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		addDialog.getContentPane().add(pathTextField, gridBagConstraints);

		jLabel5.setText("Name : ");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
		addDialog.getContentPane().add(jLabel5, gridBagConstraints);

		nameTextField.setMinimumSize(new java.awt.Dimension(200, 19));
		nameTextField.setPreferredSize(new java.awt.Dimension(400, 19));
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		addDialog.getContentPane().add(nameTextField, gridBagConstraints);

		jLabel3.setText("Value : ");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
		addDialog.getContentPane().add(jLabel3, gridBagConstraints);

		valueTextField.setMinimumSize(new java.awt.Dimension(200, 19));
		valueTextField.setPreferredSize(new java.awt.Dimension(400, 19));
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		addDialog.getContentPane().add(valueTextField, gridBagConstraints);

		okButton.setText("OK");
		okButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				okButtonActionPerformed(evt);
			}
		});

		jPanel2.add(okButton);

		cancelButton.setText("Cancel");
		jPanel2.add(cancelButton);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 4;
		gridBagConstraints.gridwidth = 2;
		addDialog.getContentPane().add(jPanel2, gridBagConstraints);

		getContentPane().setLayout(new java.awt.GridBagLayout());

		setTitle("WST Cookies");
		addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing(java.awt.event.WindowEvent evt) {
				exitForm(evt);
			}
		});

		jLabel1.setText("Cookies");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		getContentPane().add(jLabel1, gridBagConstraints);

		jScrollPane1.setPreferredSize(new java.awt.Dimension(600, 200));
		cookieTable.setModel(new javax.swing.table.DefaultTableModel(
				new Object[][] {

				}, new String[] {

				}));
		jScrollPane1.setViewportView(cookieTable);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
		getContentPane().add(jScrollPane1, gridBagConstraints);

		jLabel2.setText("Previous values");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		getContentPane().add(jLabel2, gridBagConstraints);

		jScrollPane2.setPreferredSize(new java.awt.Dimension(300, 200));
		cookieDetailTable.setModel(new javax.swing.table.DefaultTableModel(
				new Object[][] {

				}, new String[] {

				}));
		jScrollPane2.setViewportView(cookieDetailTable);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
		getContentPane().add(jScrollPane2, gridBagConstraints);

		closeButton.setText("Close");
		closeButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				closeButtonActionPerformed(evt);
			}
		});

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 4;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
		getContentPane().add(closeButton, gridBagConstraints);

		jPanel1.setLayout(new java.awt.GridBagLayout());

		addButton.setText("Add");
		addButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				addButtonActionPerformed(evt);
			}
		});

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
		gridBagConstraints.weightx = 1.0;
		jPanel1.add(addButton, gridBagConstraints);

		deleteButton.setText("Delete");
		deleteButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				deleteButtonActionPerformed(evt);
			}
		});

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
		gridBagConstraints.weightx = 1.0;
		jPanel1.add(deleteButton, gridBagConstraints);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
		gridBagConstraints.weighty = 1.0;
		getContentPane().add(jPanel1, gridBagConstraints);

		java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit()
				.getScreenSize();
		setBounds((screenSize.width - 600) / 2, (screenSize.height - 400) / 2,
				600, 400);
	}

	// </editor-fold>//GEN-END:initComponents

	private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_okButtonActionPerformed
		String domain = domainTextField.getText();
		domainTextField.setBackground("".equals(domain) ? Color.RED
				: Color.WHITE);
		String path = pathTextField.getText();
		if ("".equals(path)) {
			path = "/";
		}
		String name = nameTextField.getText();
		nameTextField.setBackground("".equals(name) ? Color.RED : Color.WHITE);
		String value = valueTextField.getText();
		if ("".equals(domain) || "".equals(name)) {
			return;
		}
		Cookie cookie = new Cookie(new Date(), name + "=" + value + "; domain="
				+ domain + "; path=" + path);
		_logger.info("Cookie is " + cookie);
		_model.addCookie(cookie);
		addDialog.setVisible(false);
	}// GEN-LAST:event_okButtonActionPerformed

	private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_deleteButtonActionPerformed
		int row = cookieDetailTable.getSelectedRow();
		if ((row < cookieDetailTable.getRowCount()) && (row > -1)) {
			Cookie cookie = _model.getCookieAt(_key, row);
			_model.removeCookie(cookie);
		}
	}// GEN-LAST:event_deleteButtonActionPerformed

	private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_addButtonActionPerformed
		addDialog.setVisible(true);
	}// GEN-LAST:event_addButtonActionPerformed

	private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_closeButtonActionPerformed
		setVisible(false);
	}// GEN-LAST:event_closeButtonActionPerformed

	/** Exit the Application */
	private void exitForm(java.awt.event.WindowEvent evt) {// GEN-FIRST:event_exitForm
		setVisible(false);
	}// GEN-LAST:event_exitForm

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JButton addButton;
	private javax.swing.JDialog addDialog;
	private javax.swing.JButton cancelButton;
	private javax.swing.JButton closeButton;
	private javax.swing.JTable cookieDetailTable;
	private javax.swing.JTable cookieTable;
	private javax.swing.JButton deleteButton;
	private javax.swing.JTextField domainTextField;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JLabel jLabel2;
	private javax.swing.JLabel jLabel3;
	private javax.swing.JLabel jLabel4;
	private javax.swing.JLabel jLabel5;
	private javax.swing.JLabel jLabel6;
	private javax.swing.JPanel jPanel1;
	private javax.swing.JPanel jPanel2;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JScrollPane jScrollPane2;
	private javax.swing.JTextField nameTextField;
	private javax.swing.JButton okButton;
	private javax.swing.JTextField pathTextField;
	private javax.swing.JTextField valueTextField;

	// End of variables declaration//GEN-END:variables

	private class CookieTableModel extends AbstractTableModel {

		private FrameworkModel _model;
		private FrameworkListener _listener = new FrameworkListener() {
			public void cookieAdded(FrameworkEvent evt) {
				Cookie cookie = evt.getCookie();
				int row = _model.getIndexOfCookie(cookie);
				int count = _model.getCookieCount(cookie.getKey());
				if (count == 1) {
					fireTableRowsInserted(row, row);
				} else {
					fireTableRowsUpdated(row, row);
				}
			}

			public void cookieRemoved(FrameworkEvent evt) {
				Cookie cookie = evt.getCookie();
				int count = _model.getCookieCount(cookie.getKey());
				if (count == 0) {
					fireTableDataChanged();
				} else {
					int row = _model.getIndexOfCookie(cookie);
					fireTableRowsUpdated(row, row);
				}
			}

			public void cookiesChanged() {
				fireTableDataChanged();
			}

			public void conversationPropertyChanged(FrameworkEvent evt) {
			}

			public void urlPropertyChanged(FrameworkEvent evt) {
			}

		};

		private String[] _columnNames = new String[] { "Domain", "Path",
				"Name", "Date", "Value", "Secure", "Max age", "Comment" };
		private Class[] _columnClass = new Class[] { String.class,
				String.class, String.class, Date.class, String.class,
				Boolean.class, String.class, String.class };

		public CookieTableModel(FrameworkModel model) {
			this._model = model;
			this._model.addModelListener(_listener);
		}

		public int getColumnCount() {
			return _columnNames.length;
		}

		public int getRowCount() {
			if (this._model == null) {
				return 0;
			}
			return this._model.getCookieCount();
		}

		public Object getValueAt(int rowIndex, int columnIndex) {
			String key = this._model.getCookieAt(rowIndex);
			Cookie cookie = this._model.getCurrentCookie(key);
			switch (columnIndex) {
			case 0:
				return cookie.getDomain();
			case 1:
				return cookie.getPath();
			case 2:
				return cookie.getName();
			case 3:
				return cookie.getDate();
			case 4:
				return cookie.getValue();
			case 5:
				return Boolean.valueOf(cookie.getSecure());
			case 6:
				return cookie.getMaxAge();
			case 7:
				return cookie.getComment();
			}
			return null;
		}

		@Override
		public String getColumnName(int columnIndex) {
			return _columnNames[columnIndex];
		}

		@Override
		public Class getColumnClass(int columnIndex) {
			return _columnClass[columnIndex];
		}

		public String getKeyAt(int row) {
			return this._model.getCookieAt(row);
		}

	}

	private class HistoricalCookieTableModel extends AbstractTableModel {

		private FrameworkModel _model = null;
		private String _key = null;

		private FrameworkListener _listener = new FrameworkListener() {
			public void cookieAdded(FrameworkEvent evt) {
				Cookie cookie = evt.getCookie();
				if ((_key == null) || !_key.equals(cookie.getKey())) {
					return;
				}
				int row = _model.getIndexOfCookie(_key, cookie);
				fireTableRowsInserted(row, row);
			}

			public void cookieRemoved(FrameworkEvent evt) {
				Cookie cookie = evt.getCookie();
				if ((_key == null) || !_key.equals(cookie.getKey())) {
					return;
				}
				fireTableDataChanged();
			}

			public void cookiesChanged() {
				fireTableDataChanged();
			}

			public void conversationPropertyChanged(FrameworkEvent evt) {
			}

			public void urlPropertyChanged(FrameworkEvent evt) {
			}

		};

		private String[] _columnNames = new String[] { "Date", "Value",
				"Secure", "Max age", "Comment" };
		private Class[] _columnClass = new Class[] { Date.class, String.class,
				Boolean.class, String.class, String.class };

		public HistoricalCookieTableModel(FrameworkModel model) {
			this._model = model;
			this._model.addModelListener(_listener);
		}

		public void setKey(String key) {
			_key = key;
			fireTableDataChanged();
		}

		public int getRowCount() {
			if (this._model == null) {
				return 0;
			}
			if (_key == null) {
				return 0;
			}
			return this._model.getCookieCount(_key);
		}

		public Object getValueAt(int row, int column) {
			Cookie cookie = this._model.getCookieAt(_key, row);
			switch (column) {
			case 0:
				return cookie.getDate();
			case 1:
				return cookie.getValue();
			case 2:
				return Boolean.valueOf(cookie.getSecure());
			case 3:
				return cookie.getMaxAge();
			case 4:
				return cookie.getComment();
			}
			return null;
		}

		public int getColumnCount() {
			return _columnNames.length;
		}

		@Override
		public String getColumnName(int columnIndex) {
			return _columnNames[columnIndex];
		}

		@Override
		public Class getColumnClass(int columnIndex) {
			return _columnClass[columnIndex];
		}

	}
}
